<?php
/**
* Base controller used by all non-admin Controllers. It provides a few default
* methods which you can easily override if needs be.
*
* Copyright (c) 2009 James Gauld <james@jamesgauld.net>
* This file is part of Scribble.
* @license http://www.scribblecms.co.uk/license.txt
*
* @package Scribble
*/
use Buan\Config;
use Buan\Controller;
use Buan\Core;
use Buan\ExtensionManager;
use Buan\UrlCommand;
use Buan\View;
abstract class ScribblePublicController extends Controller {

	/**
	* Takes the requested url command, finds a matching Page and returns the
	* resulting View.
	*
	* @return ScribblePublicView
	*/
	protected function deliverPage() {

		// First check we're not in maintenance mode
		if(SCRIBBLE_MAINTENANCE_MODE) {
			return $this->error503();
		}

		// Load page from the requested URL
		$page = PageManager::loadByUrlCommand(SiteManager::getCurrentSite(), Config::get('app.command.requested'));

		// Page not found; traverse up URL path to find a matching Page and pass the
		// path to that Page if it supports handling missing paths.
		$cr = Config::get('app.command.requested');
		if($page===NULL && strpos($cr, "/")!==FALSE) {
			$action = '';
			while(preg_match("/^(.+)?(\/[^\/]+)$/i", $cr, $m) && $page===NULL) {
				$cr = $m[1];
				$action = "{$m[2]}{$action}";
				$page = PageManager::loadByUrlCommand(SiteManager::getCurrentSite(), $cr);
			}
			if($page===NULL) {
				return NULL;
			}
			else if($page->handleSubPaths()) {
				// TODO
				die("TODO: The url you've requested doesn't map to any Pages, but one of the nodes in that url DOES. Therefore, eventually, here we will pass the remainder of that URL ({$action}) to the found Page so it can be dealt with in the same manner used by the 'unknown' controller. This will only be done if the found page is flagged as being capable of handling missing sub paths, otherwise 404 is delivered as normal.");
			}
			else {
				$page = NULL;
			}
		}

		// Page is found, and published or current user has the "page-view-unpublished"
		// privilege for this page
		if($page!==NULL && ($page->isPublished() || ScribbleAuth::authorize(ScribbleSession::getUser(), 'page-view-unpublished', $page->getPathToSite()))) {

			// Load version
			$version = $page->findVersion();

			// Get the Page's outer template view.
			$gview = $version->getOuterView();
			if($gview!==NULL) {
				View::setGlobalView($gview);
			}
			else {
				$gview = View::getGlobalView();
			}
			$gview->setHeader('Content-Type', 'text/html; charset=utf-8');
			$gview->page = $page;
			$gview->version = $version;

			// If logged in as a cms administrator, we'll also a few helpful widgets
			// to aid inline editing.
			if(ScribbleSession::isOccupied() && ScribbleAuth::authorize(ScribbleSession::getUser(), 'scribble-admin')) {
				$ur = Config::get('ext.Scribble.urlRoot');
				$gview->addStylesheets("{$ur}/inline/scribble-inline.css");
				$gview->addJavascripts(UrlCommand::createUrl('scribble', 'inline', 'js', array('p'=>$page->id)));
			}

			// Return the Page's inner template view
			return $version->getInnerView();
		}

		// Page not found so return 404 response
		else {
			return $this->error404();
		}
	}

	/**
	* Deliver a generic "not found" page.
	*
	* @return ScribblePublicView
	*/
	protected function error404() {
		header("HTTP/1.1 404");
		$view = new ScribblePublicView();
		$view->setSource(Config::get('ext.Scribble.dir.views').'/error-404.tpl.php');
		return $view;
	}

	/**
	* Deliver a generic "Servie Unavailable" page for when the system is in
	* "maintenance mode"
	*
	* @return ScribblePublicView
	*/
	protected function error503() {
		header("HTTP/1.1 503");
		$view = new ScribblePublicView();
		$view->setSource(Config::get('ext.Scribble.dir.views').'/error-503.tpl.php');
		View::setGlobalView($view);
		return new ScribblePublicView();;
	}

	/**
	* Index action.
	*
	* @param array Action parameters
	* @return ScribblePublicView
	*/
	public function index($params) {
		return $this->deliverPage();
	}

	/**
	* Unknown action.
	*
	* @param array Action parameters
	* @param string Originally requested action
	* @return ScribblePublicView
	*/
	public function unknown($params, $action) {
		return $this->deliverPage();
	}
}
?>